package cn.edu.ncu.housinghub.exception;

import cn.edu.ncu.housinghub.constant.ErrorCodeConstant;
import cn.edu.ncu.housinghub.vo.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理类
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 创建日志记录器
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler
    public Result handlerAll(Throwable throwable){
        // 记录完整的异常轨迹日志
        logger.error("全局异常处理 - 发生未预期异常: {}", throwable.getMessage(), throwable);
        // 返回错误信息
        return Result.error(ErrorCodeConstant.SYSTEM_ERROR.getCode() , throwable.getMessage());
    }

    // 处理特定的业务异常
    @ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException e) {
        // 记录业务异常日志（包含堆栈轨迹）
        if (e.getErrorCode() != null) {
            logger.warn("业务异常 - 错误码: {}, 错误信息: {}, 详细信息: {}",
                    e.getErrorCode().getCode(), e.getErrorCode().getMessage(), e.getMessage(), e);
        } else {
            logger.warn("业务异常 - 错误信息: {}", e.getMessage(), e);
        }
        // 返回错误信息
        return Result.error(e.getErrorCode().getCode(), e.getMessage());
    }

    // 处理参数验证异常
    @ExceptionHandler(org.springframework.web.bind.MethodArgumentNotValidException.class)
    public Result handleValidationException(org.springframework.web.bind.MethodArgumentNotValidException e) {
        // 记录参数验证异常日志（包含堆栈轨迹）
        logger.warn("参数验证异常: {}", e.getMessage(), e);

        // 获取具体的验证错误信息
        StringBuilder errorMsg = new StringBuilder();
        e.getBindingResult().getFieldErrors().forEach(error ->
                errorMsg.append(error.getField()).append(": ").append(error.getDefaultMessage()).append("; ")
        );

        // 返回错误信息
        return Result.error(ErrorCodeConstant.PARAM_VALIDATION_FAILED.getCode(), "参数验证失败: " + errorMsg);
    }

    // 处理违反约束异常（如@Valid验证失败）
    @ExceptionHandler(jakarta.validation.ConstraintViolationException.class)
    public Result handleConstraintViolationException(jakarta.validation.ConstraintViolationException e) {
        // 记录约束违反异常日志（包含堆栈轨迹）
        logger.warn("约束违反异常: {}", e.getMessage(), e);

        // 获取具体的验证错误信息
        StringBuilder errorMsg = new StringBuilder();
        e.getConstraintViolations().forEach(violation ->
                errorMsg.append(violation.getPropertyPath()).append(": ").append(violation.getMessage()).append("; ")
        );

        // 返回错误信息
        return Result.error(ErrorCodeConstant.CONSTRAINT_VIOLATION_ERROR.getCode(), "参数验证失败: " + errorMsg);
    }
}
